package com.zhiche.lisa.bms.service.driver.impl;

import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.baomidou.mybatisplus.plugins.Page;
import com.baomidou.mybatisplus.service.impl.ServiceImpl;
import com.zhiche.lisa.bms.dao.mapper.driver.PertrolPriceEffectiveMapper;
import com.zhiche.lisa.bms.dao.model.driver.PertrolPriceEffective;
import com.zhiche.lisa.bms.pojo.vo.driver.PertrolPriceEffectiveVO;
import com.zhiche.lisa.bms.service.driver.PertrolPriceEffectiveService;
import com.zhiche.lisa.bms.utils.ToolCommonUtils;
import com.zhiche.lisa.core.supports.BaseException;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.validation.BindingResult;
import org.springframework.validation.ObjectError;

import java.util.Date;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * <p>
 * 加油站燃油价格生效表 服务实现类
 * </p>
 *
 * @author linbao
 * @since 2019-02-28
 */
@Service
@Slf4j
public class PertrolPriceEffectiveServiceImpl extends ServiceImpl<PertrolPriceEffectiveMapper, PertrolPriceEffective>
        implements PertrolPriceEffectiveService {

    /**
     * 分页查询
     *
     * @param page
     * @return
     */
    @Override
    public Page<PertrolPriceEffectiveVO> queryPertrolPricePage(Page<PertrolPriceEffectiveVO> page) {
        if (Objects.isNull(page)) {
            return null;
        }
        page.setOrderByField("update_time").setAsc(false);
        EntityWrapper<PertrolPriceEffectiveVO> ew = whereCondition(page);
        page.setRecords(baseMapper.selectByConditions(page, ew));
        return page;
    }

    /**
     * 添加
     *
     * @param pertrolPriceEffectiveVO
     * @param br
     * @return
     */
    @Override
    public void addPertrolPrice(PertrolPriceEffectiveVO pertrolPriceEffectiveVO, BindingResult br) {
        log.info("PertrolPriceEffectiveServiceImpl.addPertrolPrice pertrolPriceEffectiveVO : {}", pertrolPriceEffectiveVO);

        if (Objects.isNull(pertrolPriceEffectiveVO)) {
            log.error("PertrolPriceEffectiveServiceImpl.addPertrolPrice param form must not be null");
            throw new BaseException("加油站燃油价格变动表单不能为空");
        }
        // 时间格式化
        if (Objects.nonNull(pertrolPriceEffectiveVO.getEffectiveDate())) {
            pertrolPriceEffectiveVO.setEffectiveDate(ToolCommonUtils.getStartOfDate(pertrolPriceEffectiveVO.getEffectiveDate()));
        }
        if (Objects.nonNull(pertrolPriceEffectiveVO.getInvalidDate())) {
            pertrolPriceEffectiveVO.setInvalidDate(ToolCommonUtils.getStartOfDate(pertrolPriceEffectiveVO.getInvalidDate()));
        }

        // 验证表单
        verificationForm(br);
        // 验证业务
        // verificationBusiness(pertrolPriceEffectiveVO);
        verificationDate(pertrolPriceEffectiveVO);


        // 查询当前生效的记录，更新失效时间未添加记录的生效时间
        PertrolPriceEffective currentPrice = this.selectByEffectiveDateAndFuelTypeId(pertrolPriceEffectiveVO.getFuelTypeId(),
                pertrolPriceEffectiveVO.getEffectiveDate());
        if (Objects.nonNull(currentPrice)) {
            currentPrice.setInvalidDate(pertrolPriceEffectiveVO.getEffectiveDate());
            this.updateById(currentPrice);
        }
        PertrolPriceEffective effective = new PertrolPriceEffective();
        BeanUtils.copyProperties(pertrolPriceEffectiveVO, effective);
        this.insert(effective);
    }

    /**
     * 根据燃油类型得到最新的燃油价格
     *
     * @param fuelTypeId
     * @param effectiveDate
     * @return
     */
    @Override
    public PertrolPriceEffective selectByEffectiveDateAndFuelTypeId(Integer fuelTypeId, Date effectiveDate) {
        log.info("PertrolPriceEffectiveServiceImpl.selectByEffectiveDateAndFuelTypeId params : {}, {}", fuelTypeId, effectiveDate);
        // 校验参数
        validateParam(fuelTypeId, effectiveDate);
        List<PertrolPriceEffective> list = getPriceEffectiveList(fuelTypeId, effectiveDate, true);
        if (CollectionUtils.isEmpty(list)) {
            list = getPriceEffectiveList(fuelTypeId, effectiveDate, false);
        }
        if (CollectionUtils.isNotEmpty(list)) {
            return list.get(0);
        }
        return null;
    }

    private List<PertrolPriceEffective> getPriceEffectiveList(Integer fuelTypeId, Date effectiveDate, boolean isNull) {
        EntityWrapper<PertrolPriceEffective> ew = new EntityWrapper<>();
        ew.eq("fuel_type_id", fuelTypeId).le("effective_date", effectiveDate);
        if (isNull) {
            ew.and("invalid_date is null");
        } else {
            ew.gt("invalid_date", effectiveDate);
        }
        return this.selectList(ew);
    }

    /**
     * 校验参数
     *
     * @param fuelTypeId
     * @param effectiveDate
     */
    private void validateParam(Integer fuelTypeId, Date effectiveDate) {
        if (Objects.isNull(fuelTypeId)) {
            log.error("PertrolPriceEffectiveServiceImpl.selectByEffectiveDateAndFuelTypeId param fuelTypeId must not be null");
            throw new BaseException("燃油类型主键不能为空");
        }

        if (Objects.isNull(effectiveDate)) {
            log.error("PertrolPriceEffectiveServiceImpl.selectByEffectiveDateAndFuelTypeId param effectiveDate must not be null");
            throw new IllegalArgumentException("生效时间不能为空");
        }
    }

    /**
     * 表单验证
     *
     * @param br
     */
    private void verificationForm(BindingResult br) {
        if (null == br) {
            log.error("PertrolPriceEffectiveServiceImpl.verificationForm error br is null");
            throw new IllegalArgumentException("BindingResult is null");
        }

        if (br.hasErrors()) {
            List<ObjectError> list = br.getAllErrors();
            log.error("PertrolPriceEffectiveServiceImpl.verificationForm error : {}", list.get(0).getDefaultMessage());
            throw new BaseException(list.get(0).getDefaultMessage());
        }
    }

    /**
     * //  * 验证业务
     * //  *
     * //  * @param form
     * //
     */
    // private void verificationBusiness(PertrolPriceEffectiveVO form) {
    //     log.info("PertrolPriceEffectiveServiceImpl.verificationBusiness param : {}", form);
    //
    //     EntityWrapper<PertrolPriceEffective> ew = new EntityWrapper<>();
    //     ew.eq("fuel_type_id", form.getFuelTypeId());
    //     List<PertrolPriceEffective> list = this.selectList(ew);
    //     // if (CollectionUtils.isEmpty(list)) {
    //     //     return;
    //     // }
    //     if (CollectionUtils.isNotEmpty(list)) {
    //
    //         // 是否已经存在未激活的里程变动激活时间大于
    //         List<PertrolPriceEffective> collect = list.stream()
    //                 .filter(o -> -1 != o.getEffectiveDate().compareTo(new DateTime().withMillisOfDay(0).toDate())).collect(Collectors.toList());
    //         if (CollectionUtils.isNotEmpty(collect)) {
    //             if (Objects.nonNull(form.getId())) {
    //                 if (CollectionUtils.isNotEmpty(collect.stream().filter(o -> o.getId().equals(form.getId())).collect(Collectors.toList()))) {
    //                     return;
    //                 }
    //             }
    //             if (1 < collect.size()) {
    //                 log.error("PertrolPriceEffectiveServiceImpl.verificationBusiness already exist not active record");
    //                 throw new BaseException("油价变动已经存在未生效的记录");
    //             }
    //             PertrolPriceEffective effective = collect.get(0);
    //             if (Objects.nonNull(form.getId()) && form.getId().equals(effective.getId())) {
    //                 return;
    //             }
    //             if (form.getEffectiveDate().compareTo(effective.getEffectiveDate()) == 1) {
    //                 return;
    //             }
    //             log.error("PertrolPriceEffectiveServiceImpl.verificationBusiness already exist not active record");
    //             throw new BaseException("油价变动已经存在未生效的记录");
    //         }
    //     }
    // }
    private void verificationDate(PertrolPriceEffectiveVO form) {
        EntityWrapper<PertrolPriceEffective> ew = new EntityWrapper<>();
        ew.eq("fuel_type_id", form.getFuelTypeId());
        ew.ge("effective_date", form.getEffectiveDate());
        ew.andNew().le("invalid_date", form.getEffectiveDate()).or().isNull("invalid_date");
        List<PertrolPriceEffective> list = this.selectList(ew);
        if (CollectionUtils.isNotEmpty(list)) {
            if (Objects.nonNull(form.getId())) {
                if (CollectionUtils.isNotEmpty(list.stream().filter(o -> o.getId().equals(form.getId())).collect(Collectors.toList()))) {
                    return;
                }
            }
            if (list.size() >= 1) {
                log.error("PertrolPriceEffectiveServiceImpl.verificationBusiness already exist not active record");
                throw new BaseException("油价变动已经存在未生效的记录");
            }
            PertrolPriceEffective effective = list.get(0);
            if (Objects.nonNull(form.getId()) && form.getId().equals(effective.getId())) {
                return;
            }
            if (form.getEffectiveDate().compareTo(effective.getEffectiveDate()) == 1) {
                return;
            }
            log.error("PertrolPriceEffectiveServiceImpl.verificationBusiness already exist not active record");
            throw new BaseException("油价变动已经存在未生效的记录");
        }
    }

    /**
     * 条件
     *
     * @param page
     * @return
     */
    private EntityWrapper<PertrolPriceEffectiveVO> whereCondition(Page<PertrolPriceEffectiveVO> page) {
        EntityWrapper<PertrolPriceEffectiveVO> ew = new EntityWrapper<>();
        //条件
        if (Objects.nonNull(page.getCondition())) {
            // 类型id
            if (Objects.nonNull(page.getCondition().get("fuelTypeId")) && StringUtils.isNotEmpty(page.getCondition().get("fuelTypeId").toString())) {
                ew.eq("fuel_type_id", page.getCondition().get("fuelTypeId").toString().trim());
            }
            //名称
            if (Objects.nonNull(page.getCondition().get("name")) && StringUtils.isNotEmpty(page.getCondition().get("name").toString())) {
                ew.like("name", page.getCondition().get("name").toString().trim());
            }
            // 有效期
            if (Objects.nonNull(page.getCondition().get("invalidDate")) && StringUtils.isNotEmpty(page.getCondition().get("effectiveDate").toString())) {
                ew.lt("invalid_date", page.getCondition().get("invalidDate").toString().trim());
            }
            // 有效期
            if (Objects.nonNull(page.getCondition().get("effectiveDate")) && StringUtils.isNotEmpty(page.getCondition().get("effectiveDate").toString())) {
                ew.ge("effective_date", page.getCondition().get("effectiveDate").toString().trim());
            }
        }
        return ew;
    }
}
